package tpase.GlobalServer.DAO;

import it.unisa.dia.gas.jpbc.Pairing;
import tpase.GlobalServer.DO.GroupGenerator;
import tpase.GlobalServer.DO.PublicCommitment;
import tpase.util.JDBCUtil;
import tpase.util.Util;

import java.io.ByteArrayInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class PublicCommitmentDao {
    public void clearPublicCommitment() {
        Connection connection = JDBCUtil.getConnect();
        String sql = "DELETE FROM public_commitment";
        PreparedStatement statement = null;
        try {
            statement = connection.prepareCall(sql);
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement);
        }
    }

    public void storePublicCommitment(PublicCommitment publicCommitment) {
        Connection connection = JDBCUtil.getConnect();
        String sql = "INSERT INTO public_commitment (key_server_id, gamma_1_si, gamma_t_si) VALUES (?, ?, ?)";
        PreparedStatement statement = null;
        try {
            statement = connection.prepareCall(sql);
            statement.setString(1, publicCommitment.getKeyServerId());
            statement.setBinaryStream(2, new ByteArrayInputStream(publicCommitment.getGamma_1_si()));
            statement.setBinaryStream(3, new ByteArrayInputStream(publicCommitment.getGamma_t_si()));
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement);
        }
    }

    public void storePublicCommitment(List<PublicCommitment> publicCommitmentList) {
        Connection connection = JDBCUtil.getConnect();
        String sql = "INSERT INTO public_commitment (key_server_id, gamma_1_si, gamma_t_si) VALUES (?, ?, ?)";
        PreparedStatement statement = null;
        try {
            statement = connection.prepareStatement(sql);
            for (PublicCommitment publicCommitment : publicCommitmentList) {
                statement.setString(1, publicCommitment.getKeyServerId());
                statement.setBinaryStream(2, new ByteArrayInputStream(publicCommitment.getGamma_1_si()));
                statement.setBinaryStream(3, new ByteArrayInputStream(publicCommitment.getGamma_t_si()));
                statement.addBatch();
            }
            statement.executeBatch();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement);
        }
    }

    public PublicCommitment getPublicCommitment(String keyServerId) {
        Connection connection = JDBCUtil.getConnect();
        String sql = "SELECT key_server_id, gamma_1_si, gamma_t_si FROM public_commitment WHERE key_server_id = ?";
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        PublicCommitment publicCommitment = null;
        try {
            statement = connection.prepareCall(sql);
            statement.setString(1, keyServerId);
            resultSet = statement.executeQuery();
            if (resultSet.next()) {
                publicCommitment = new PublicCommitment(resultSet.getString("key_server_id"), resultSet.getBytes("gamma_1_si"), resultSet.getBytes("gamma_t_si"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement, resultSet);
        }
        if (publicCommitment == null) {
            throw new RuntimeException("getPublicCommitment, 查询公开承诺不存在");
        }
        return publicCommitment;
    }

    public List<PublicCommitment> getPublicCommitment() {
        Connection connection = JDBCUtil.getConnect();
        String sql = "SELECT key_server_id, gamma_1_si, gamma_t_si FROM public_commitment";
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        List<PublicCommitment> publicCommitmentList = new ArrayList<>();
        try {
            statement = connection.prepareCall(sql);
            resultSet = statement.executeQuery();
            while (resultSet.next()) {
                String keyServerId = resultSet.getString("key_server_id");
                byte[] gamma_1_si = resultSet.getBytes("gamma_1_si");
                byte[] gamma_t_si = resultSet.getBytes("gamma_t_si");
                publicCommitmentList.add(new PublicCommitment(keyServerId, gamma_1_si, gamma_t_si));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(connection, statement, resultSet);
        }
        return publicCommitmentList;
    }

    public static void main(String[] args) {
        PublicCommitmentDao publicCommitmentDao = new PublicCommitmentDao();
        publicCommitmentDao.clearPublicCommitment();
        final String jpbcPath = "config/a.properties";
        Pairing pairing = Util.getPairing(jpbcPath);
        String id = pairing.getZr().newRandomElement().toString();
        byte[] gamma_1_si = pairing.getZr().newRandomElement().toBytes();
        byte[] gamma_t_si = pairing.getZr().newRandomElement().toBytes();
        List<PublicCommitment> list = new ArrayList<>();
        list.add(new PublicCommitment(id, gamma_1_si, gamma_t_si));
        list.add(new PublicCommitment("22", gamma_1_si, gamma_t_si));

        System.out.println(pairing.getZr().newElementFromBytes(gamma_1_si).toString());
        System.out.println(pairing.getZr().newElementFromBytes(gamma_t_si).toString());

        publicCommitmentDao.storePublicCommitment(list);


        PublicCommitment publicCommitment2 = publicCommitmentDao.getPublicCommitment("22");
        System.out.println(pairing.getZr().newElementFromBytes(publicCommitment2.getGamma_1_si()).toString());
        System.out.println(pairing.getZr().newElementFromBytes(publicCommitment2.getGamma_t_si()).toString());
    }
}
